iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0

前言

在上一篇文章中,我們認識了Postman以及一個FHIR API Request可能包含的內容。

不過,就算知道FHIR Server的網址,也不能直接假設它一定支援所有Resource、搜尋參數及HTTP方法。

例如,有些FHIR Server可能:

  • 允許讀取Patient,但不允許新增
  • 支援Observation,卻不支援MedicationRequest
  • 允許GET,但不開放DELETE
  • 要求使用者先完成身分驗證
  • 只支援特定FHIR版本
  • 要求Resource符合特定Profile

在正式與FHIR Server溝通前,Client需要先了解Server能夠提供哪些功能。

FHIR使用CapabilityStatement描述這些資訊,而RESTful FHIR Server通常會透過metadata端點提供自己的CapabilityStatement。

今天不進行任何實際操作,而是從概念及範例了解metadata與CapabilityStatement。


metadata是什麼?

在FHIR RESTful API中,可以使用以下形式取得Server的能力資訊:

GET [base]/metadata

其中:

[base]

代表FHIR Server的Base URL。

假設一台虛構FHIR Server的Base URL是:

https://hospital.example.org/fhir

那麼它的metadata位置就是:

https://hospital.example.org/fhir/metadata

這個Request的意思不是查詢病人或檢驗結果,而是詢問FHIR Server:

你使用哪個FHIR版本?支援哪些Resource及API功能?

Server通常會回傳一筆CapabilityStatement Resource。


CapabilityStatement是什麼?

CapabilityStatement可以理解成FHIR Server的「能力說明書」。

它可能描述:

  • Server使用的FHIR版本
  • 支援的資料格式
  • 支援哪些Resource
  • 每種Resource支援哪些互動
  • 支援哪些搜尋參數
  • 是否需要身分驗證
  • 使用哪些安全機制
  • 支援哪些Profile
  • Server軟體及實作資訊
  • API服務位置

因此,Client不應該只知道對方是FHIR Server,就直接假設所有功能都可以使用。

應該先查看CapabilityStatement,再依照Server實際宣告的能力建立Request。


CapabilityStatement本身也是Resource

CapabilityStatement不是一份與FHIR無關的說明文字,它本身也是FHIR Resource。

一份經過簡化的CapabilityStatement可能如下:

{
  "resourceType": "CapabilityStatement",
  "id": "example-capability",
  "status": "active",
  "date": "2026-09-03",
  "kind": "instance",
  "software": {
    "name": "Example FHIR Server",
    "version": "1.0.0"
  },
  "implementation": {
    "description": "範例醫院FHIR Server",
    "url": "https://hospital.example.org/fhir"
  },
  "fhirVersion": "4.0.1",
  "format": [
    "json",
    "xml"
  ]
}

最外層可以看到:

"resourceType": "CapabilityStatement"

表示這是一筆CapabilityStatement Resource。

它和Patient、Observation一樣,都遵循FHIR Resource的基本結構,只是用途不同。


status:CapabilityStatement的狀態

"status": "active"

status表示這份CapabilityStatement目前的發布狀態。

可能使用的代碼包括:

代碼 基本意義
draft 草稿
active 正式使用中
retired 已停止使用
unknown 狀態未知

如果值是:

active

表示這份CapabilityStatement目前處於有效使用狀態。

這個status描述的是CapabilityStatement文件本身,不是FHIR Server當下有沒有在線,也不是病人的醫療狀態。


kind:這份CapabilityStatement描述什麼?

"kind": "instance"

kind說明這份CapabilityStatement的用途。

FHIR R4常見的值包括:

代碼 基本意義
instance 描述某一個實際運作的系統
capability 描述系統可能提供的能力
requirements 描述某個使用情境所需要的能力

從特定FHIR Server的metadata取得的CapabilityStatement,通常會使用:

"kind": "instance"

因為它描述的是目前這台實際Server的能力。


software:Server使用的軟體

"software": {
  "name": "Example FHIR Server",
  "version": "1.0.0"
}

software可以說明提供FHIR服務的軟體資訊。

常見欄位包括:

  • name:軟體名稱
  • version:軟體版本
  • releaseDate:發布日期

軟體版本和FHIR版本是不同概念。

例如:

  • Server軟體版本可能是1.0.0
  • FHIR版本可能是4.0.1

不能因為軟體版本中出現數字4,就認為它一定使用FHIR R4。


implementation:實際服務資訊

"implementation": {
  "description": "範例醫院FHIR Server",
  "url": "https://hospital.example.org/fhir"
}

implementation描述這項實際FHIR服務。

常見欄位包括:

欄位 用途
description 服務說明
url FHIR服務的Base URL
custodian 維護或管理服務的機構

其中:

"url": "https://hospital.example.org/fhir"

表示這台FHIR Server提供服務的基本位置。


fhirVersion:FHIR版本

"fhirVersion": "4.0.1"

fhirVersion是CapabilityStatement中非常重要的欄位。

常見FHIR版本包括:

  • DSTU2
  • STU3
  • R4
  • R4B
  • R5

FHIR R4的版本號是:

4.0.1

不同FHIR版本的Resource、欄位、代碼及規則可能不同,所以Client需要確認Server使用的版本是否符合自己的需求。

本系列以FHIR R4為主,因此看到:

"fhirVersion": "4.0.1"

就表示Server使用的版本與本系列相符。


format:支援的資料格式

"format": [
  "json",
  "xml"
]

format表示Server支援哪些FHIR資料格式。

常見格式包括:

  • JSON
  • XML

因為format是一個Array,所以Server可以同時宣告支援多種格式。

有些CapabilityStatement可能使用較完整的MIME Type,例如:

"format": [
  "application/fhir+json",
  "application/fhir+xml"
]

如果Client希望收到FHIR JSON,可以透過HTTP Header表示:

Accept: application/fhir+json

但Server實際支援哪些格式,仍然應以CapabilityStatement為準。


rest:RESTful API的能力

CapabilityStatement中的rest欄位,用來描述FHIR RESTful API相關能力。

簡化範例如下:

"rest": [
  {
    "mode": "server",
    "resource": [
      {
        "type": "Patient"
      },
      {
        "type": "Observation"
      }
    ]
  }
]

其中:

"mode": "server"

表示這份內容描述Server端提供的FHIR RESTful能力。

如果是:

"mode": "client"

則表示描述某個Client預期使用或支援的能力。


resource:Server支援哪些Resource?

rest.resource中,可以找到Server支援的Resource類型。

例如:

"resource": [
  {
    "type": "Patient"
  },
  {
    "type": "Observation"
  },
  {
    "type": "Encounter"
  }
]

這表示Server宣告支援:

  • Patient
  • Observation
  • Encounter

如果清單中沒有MedicationRequest,可能代表Server沒有宣告提供MedicationRequest的RESTful服務。

不過,CapabilityStatement可能很長,實際閱讀時要確認自己查看的是正確的rest區段及Server模式。


interaction:支援哪些Resource操作?

Server支援Patient,不代表Patient的所有操作都能使用。

CapabilityStatement會透過interaction說明每種Resource支援哪些互動。

例如:

{
  "type": "Patient",
  "interaction": [
    {
      "code": "read"
    },
    {
      "code": "search-type"
    },
    {
      "code": "create"
    },
    {
      "code": "update"
    }
  ]
}

可能的互動包括:

interaction code 意義
read 讀取一筆Resource
vread 讀取特定歷史版本
search-type 搜尋特定類型Resource
create 建立Resource
update 更新Resource
patch 修改部分內容
delete 刪除Resource
history-instance 查看單一Resource歷史紀錄
history-type 查看某類Resource歷史紀錄

上面的範例表示Patient支援:

  • 讀取
  • 搜尋
  • 建立
  • 更新

但沒有宣告delete,所以不能直接假設Client可以刪除Patient。


同一台Server對不同Resource可能有不同能力

假設CapabilityStatement中寫著:

"resource": [
  {
    "type": "Patient",
    "interaction": [
      {
        "code": "read"
      },
      {
        "code": "search-type"
      }
    ]
  },
  {
    "type": "Observation",
    "interaction": [
      {
        "code": "read"
      }
    ]
  }
]

這表示:

Resource read search-type
Patient 支援 支援
Observation 支援 未宣告支援

即使Patient和Observation都存在於同一台FHIR Server,它們允許的操作仍然可能不同。

所以判斷Server能力時,不能只查看Resource名稱,也要查看該Resource底下的interaction


searchParam:支援哪些搜尋參數?

CapabilityStatement也能列出Resource支援的搜尋參數。

例如:

{
  "type": "Patient",
  "searchParam": [
    {
      "name": "name",
      "definition": "http://hl7.org/fhir/SearchParameter/Patient-name",
      "type": "string"
    },
    {
      "name": "birthdate",
      "definition": "http://hl7.org/fhir/SearchParameter/individual-birthdate",
      "type": "date"
    },
    {
      "name": "identifier",
      "definition": "http://hl7.org/fhir/SearchParameter/Patient-identifier",
      "type": "token"
    }
  ]
}

這表示Server宣告支援以下Patient搜尋參數:

  • name
  • birthdate
  • identifier

搜尋URL的概念可能是:

GET /Patient?name=王小明
GET /Patient?birthdate=2000-01-01
GET /Patient?identifier=MRN0001

不同搜尋參數具有不同型別,例如:

SearchParameter type 常見用途
string 姓名或一般文字
date 日期
token 代碼或Identifier
reference Resource Reference
number 數值
quantity 數值及單位
uri URI
composite 多個條件組合

搜尋參數名稱看起來合理,不代表Server一定支援,仍要查看CapabilityStatement。


profile:Resource符合哪些Profile?

FHIR基礎規範保留一定彈性,實際使用時可能透過Profile限制Resource。

CapabilityStatement中的Resource可以宣告支援的Profile,例如:

{
  "type": "Patient",
  "profile": "https://example.org/fhir/StructureDefinition/example-patient"
}

這表示Server處理Patient時,可能要求或宣告符合指定的Patient Profile。

另外,也可能透過supportedProfile列出其他支援的Profile。

Profile可能規定:

  • 哪些欄位必填
  • 欄位可以出現幾次
  • 使用哪一種代碼系統
  • Identifier應如何表示
  • 可以使用哪些Extension
  • Resource之間如何建立關係

因此,知道Server支援Patient仍然不夠,還要確認它支援或要求哪一個Patient Profile。


security:安全與身分驗證

CapabilityStatement可以在rest.security中描述安全相關資訊。

簡化範例如下:

"security": {
  "cors": true,
  "service": [
    {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/restful-security-service",
          "code": "SMART-on-FHIR",
          "display": "SMART-on-FHIR"
        }
      ]
    }
  ],
  "description": "使用SMART on FHIR進行授權"
}

它可能說明:

  • 是否支援CORS
  • 使用哪種安全服務
  • 是否支援SMART on FHIR
  • 身分驗證及授權的文字說明

不過,CapabilityStatement不會因為列出安全服務,就自動提供帳號或Access Token。

Client仍然需要依照該系統的授權流程取得合法權限。


system interaction:系統層級的互動

除了各Resource自己的interaction,CapabilityStatement也可以列出系統層級的互動。

例如:

"interaction": [
  {
    "code": "transaction"
  },
  {
    "code": "batch"
  },
  {
    "code": "search-system"
  }
]

可能的用途包括:

code 基本意義
transaction 將多個操作當成一組交易處理
batch 一次送出多個彼此獨立的操作
search-system 跨Resource類型搜尋
history-system 查看Server層級歷史紀錄

這裡的interaction和特定Resource下的interaction位置不同。

  • rest.resource.interaction描述某一種Resource的能力。
  • rest.interaction描述整個系統層級的能力。

operation:Server提供的額外操作

FHIR除了read、create及update等標準互動,也可以定義Operation。

Operation的名稱通常會以$開頭,例如:

$validate
$everything

CapabilityStatement可以透過operation列出Server支援的Operation。

簡化範例如下:

"operation": [
  {
    "name": "validate",
    "definition": "http://hl7.org/fhir/OperationDefinition/Resource-validate"
  }
]

這表示Server宣告支援$validate,可以用來檢查Resource是否符合相關規則。

不是所有FHIR Server都支援相同Operation,使用前仍要查看CapabilityStatement及該Server文件。


CapabilityStatement的內容層次

一份完整的CapabilityStatement可能非常長,可以先依照以下層次閱讀:

CapabilityStatement
├── 基本資料
│   ├── status
│   ├── date
│   └── kind
│
├── Server資訊
│   ├── software
│   └── implementation
│
├── FHIR規格
│   ├── fhirVersion
│   └── format
│
└── RESTful能力
    └── rest
        ├── mode
        ├── security
        ├── resource
        │   ├── type
        │   ├── profile
        │   ├── interaction
        │   └── searchParam
        ├── interaction
        └── operation

第一次看到時,不需要理解所有欄位,可以先找:

  1. resourceType
  2. status
  3. kind
  4. fhirVersion
  5. format
  6. rest.mode
  7. rest.resource.type
  8. interaction.code
  9. searchParam.name

一份較完整的簡化範例

以下CapabilityStatement宣告Server使用FHIR R4、支援JSON與XML,也提供Patient的read及search-type。

{
  "resourceType": "CapabilityStatement",
  "id": "example-capability",
  "status": "active",
  "date": "2026-09-03",
  "kind": "instance",
  "software": {
    "name": "Example FHIR Server",
    "version": "1.0.0"
  },
  "implementation": {
    "description": "範例醫院FHIR服務",
    "url": "https://hospital.example.org/fhir"
  },
  "fhirVersion": "4.0.1",
  "format": [
    "application/fhir+json",
    "application/fhir+xml"
  ],
  "rest": [
    {
      "mode": "server",
      "resource": [
        {
          "type": "Patient",
          "interaction": [
            {
              "code": "read"
            },
            {
              "code": "search-type"
            }
          ],
          "searchParam": [
            {
              "name": "name",
              "type": "string"
            },
            {
              "name": "birthdate",
              "type": "date"
            }
          ]
        }
      ]
    }
  ]
}

從這份資料可以解讀出:

問題 答案
這是什麼Resource? CapabilityStatement
是否為有效狀態? 是,statusactive
描述實際Server嗎? 是,kindinstance
使用哪個FHIR版本? FHIR R4 4.0.1
支援哪些格式? FHIR JSON及XML
支援哪個Resource? Patient
Patient可以讀取嗎? 可以,支援read
Patient可以搜尋嗎? 可以,支援search-type
支援哪些搜尋參數? namebirthdate
有宣告可以刪除Patient嗎? 沒有看到delete

沒有宣告,就一定不支援嗎?

原則上,Client應依照CapabilityStatement宣告的內容判斷Server能力。

如果CapabilityStatement沒有列出某項Resource或互動,就不應直接假設它可以使用。

但實務上仍可能遇到:

  • CapabilityStatement沒有及時更新
  • Server文件與實際功能不一致
  • 功能受到帳號權限影響
  • 不同Endpoint具有不同設定
  • 某些能力需要另外查看實作指引
  • CapabilityStatement非常龐大,閱讀時漏掉相關內容

因此,CapabilityStatement是重要依據,但正式系統整合時仍需要搭配:

  • API文件
  • Implementation Guide
  • Profile
  • 測試報告
  • 權限說明
  • 系統供應商文件
  • 雙方串接規格

CapabilityStatement和Implementation Guide的差異

這兩個名詞容易混淆。

CapabilityStatement

主要回答:

這個系統支援哪些FHIR功能?

例如:

  • 使用FHIR R4
  • 支援Patient
  • Patient可以read及search
  • 支援JSON

Implementation Guide

主要回答:

在特定國家、組織或使用情境中,FHIR應該如何使用?

例如:

  • Patient哪些欄位必填
  • 身分證字號如何表示
  • 地址如何表示
  • 使用哪些CodeSystem及ValueSet
  • Resource之間如何連結

可以簡單整理:

項目 主要用途
CapabilityStatement 描述系統能力
Implementation Guide 定義特定情境的實作規則

一台Server可能透過CapabilityStatement宣告支援某個Implementation Guide中的Profile。


為什麼metadata很重要?

如果沒有先了解Server能力,Client可能直接提出Server無法處理的Request。

例如:

  • 對只允許read的Patient使用DELETE
  • 使用Server不支援的搜尋參數
  • 傳送XML給只支援JSON的Server
  • 使用FHIR R5格式傳給R4 Server
  • 傳送不符合指定Profile的Resource
  • 未完成授權就要求取得敏感資料

CapabilityStatement能讓Client在建立Request前,先了解Server提供的功能及限制。

可以將metadata想成餐廳的菜單與服務說明:

  • 有哪些餐點?
  • 可以使用哪些點餐方式?
  • 是否需要訂位?
  • 接受哪些付款方式?
  • 有哪些限制?

顧客先看菜單,才能依照餐廳真正提供的服務點餐。


今日小結

今天認識了FHIR Server的能力說明方式。

FHIR RESTful Server通常會透過:

GET [base]/metadata

提供CapabilityStatement。

CapabilityStatement可以說明:

  • Server使用的FHIR版本
  • 支援的資料格式
  • 支援哪些Resource
  • 各Resource支援哪些interaction
  • 可以使用哪些搜尋參數
  • 支援哪些Profile及Operation
  • 使用哪些安全機制
  • Server軟體及實作資訊

我認為今天最重要的觀念是:

知道對方是FHIR Server,不代表它支援FHIR規範中的所有功能。

Client應先了解CapabilityStatement,再依照Server真正宣告的能力設計資料交換方式。

下一篇將介紹FHIR的read互動,看看系統知道Resource類型及id後,如何表示「讀取一筆Patient」,以及成功與失敗時可能收到什麼Response。

明日預告

Day 17|第一次用API讀取Patient資料

參考資料

  1. HL7 FHIR R4:CapabilityStatement
    https://hl7.org/fhir/R4/capabilitystatement.html

  2. HL7 FHIR R4:RESTful API-Capabilities
    https://hl7.org/fhir/R4/http.html#capabilities

  3. HL7 FHIR R4:Search
    https://hl7.org/fhir/R4/search.html

  4. HL7 FHIR R4:Operations
    https://hl7.org/fhir/R4/operations.html

  5. HL7 FHIR R4:Profiling FHIR
    https://hl7.org/fhir/R4/profiling.html


上一篇
Day 15|安裝Postman並送出第一個API請求
下一篇
Day 17|第一次用API讀取Patient資料
系列文
《醫資生的 FHIR 30日入門:用 Postman 讀懂醫療資料交換》30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言